////////////////////////////////////////////////////////////////////////////////
// Filename: graphics.cpp
////////////////////////////////////////////////////////////////////////////////
#include "graphics.hpp"

Graphics::Graphics() {
	m_direct3D = NULL;
	shader = NULL;
	m_textureShader = NULL;
	camera = NULL;
	m_renderQueue = NULL;
}

Graphics::~Graphics() {

}

bool Graphics::Initialize(int width, int height, HWND hWnd) {
	bool result;

	m_direct3D = new Direct3D();
	if (!m_direct3D) {
		return false;
	}

	result = m_direct3D->Initialize(width, height, true, hWnd, false, 1000.0f, 1.0f);
	if (!result) {
		return false;
	}

	camera = new Camera();
	if (!camera) {
		return false;
	}

	camera->SetPosition(0.0f, 0.0f, -10.0f);

	shader = new miv::PositionColorShader();
	if (!shader) {
		return false;
	}

	result = shader->Initialize(m_direct3D->GetDevice(), hWnd);
	if (!result) {
		return false;
	}

	m_textureShader = new PositionTextureShader();
	if (!m_textureShader) {
		return false;
	}

	result = m_textureShader->Initialize(m_direct3D->GetDevice(), hWnd);
	if (!result) {
		return false;
	}

	m_renderQueue = new std::queue<miv::IRenderble*>();
	if (!m_renderQueue) {
		return false;
	}

	return true;
}

void Graphics::Shutdown() {
	if (m_textureShader) {
		m_textureShader->Shutdown();
		delete m_textureShader;
		m_textureShader = NULL;
	}
	if (shader) {
		shader->Shutdown();
		delete shader;
		shader = NULL;
	}

	if (camera) {
		delete camera;
		camera = NULL;
	}

	if (m_direct3D) {
		m_direct3D->Shutdown();
		delete m_direct3D;
		m_direct3D = NULL;
	}

	if (m_renderQueue) {
		delete m_renderQueue;
		m_renderQueue = NULL;
	}
}

void Graphics::BeginScene(float red, float green, float blue, float alpha) {
	m_direct3D->BeginScene(red, green, blue, alpha);
}

void Graphics::EndScene() {
	m_direct3D->EndScene();
}

Camera* Graphics::GetCamera() {
	return camera;
}

miv::PositionColorShader* Graphics::GetShader() {
	return shader;
}

PositionTextureShader* Graphics::GetTextureShader() {
	return m_textureShader;
}

void Graphics::GetWorldMatrix(D3DXMATRIX& world) {
	//m_direct3D->GetWorldMatrix(world);
}

void Graphics::GetProjectionMatrix(D3DXMATRIX& projection) {
	//m_direct3D->GetProjectionMatrix(projection);
}

Direct3D* Graphics::GetDirect3D() {
	return m_direct3D;
}

void Graphics::Rotate(Matrix* iM, float x, float y, float z) {
	Matrix output;
	D3DXMatrixRotationYawPitchRoll(&output, x, y, z);
	*iM *= output;
}

void Graphics::RotateX(Matrix* iM, float x) {
	Matrix output;
	D3DXMatrixRotationX(&output, x);
	*iM *= output;
}

void Graphics::RotateY(Matrix* iM, float y) {
	Matrix output;
	D3DXMatrixRotationY(&output, y);
	*iM *= output;
}

void Graphics::RotateZ(Matrix* iM, float z) {
	Matrix output;
	D3DXMatrixRotationZ(&output, z);
	*iM *= output;
}

void Graphics::Translate(Matrix* iM, float x, float y, float z) {
	Matrix output;
	D3DXMatrixTranslation(&output, x, y, z);
	*iM *= output;
}

void Graphics::TranslateX(Matrix* iM, float x) {
	Matrix output;
	D3DXMatrixTranslation(&output, x, 0.0f, 0.0f);
	*iM *= output;
}

void Graphics::TranslateY(Matrix* iM, float y) {
	Matrix output;
	D3DXMatrixTranslation(&output, 0.0f, y, 0.0f);
	*iM *= output;
}

void Graphics::TranslateZ(Matrix* iM, float z) {
	Matrix output;
	D3DXMatrixTranslation(&output, 0.0f, 0.0f, z);
	*iM *= output;
}
